/*
 * This code was created by Jeff Molofee '99
 * (ported to Linux/SDL by Ti Leggett '01)
 *
 * If you've found this code useful, please let me know.
 *
 * Visit Jeff at http://nehe.gamedev.net/
 *
 * or for port-specific comments, questions, bugreports etc.
 * email to leggett@eecs.tulane.edu
 */

#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
#include <iostream>

#include <string>
#include "SDL/SDL.h"

#include "libraries/BM_input.h"
#include "libraries/BM_level.h"
#include "libraries/BM_anitex.h"
#include "libraries/BM_menu.h"
#include "libraries/BM_menu_object.h"
#include "libraries/BM_time.h"
#include "libraries/BM_sound.h"
#include "libraries/BM_init.h"

/* screen width, height, and bit depth */
#define SCREEN_WIDTH  640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP     16

/* Set up some booleans */
#define TRUE  1
#define FALSE 0

enum BM_SCREENS{BM_MENU,BM_GAME};


using namespace std;

/*******************************************************************************/

/* This is our SDL surface */
SDL_Surface *screen;
int cur;
BMKeyboard keyboard;
float x, y, z;
float x_rot, y_rot, z_rot;
int bmGameLoop();
	BMTex my_bm_tex;
	BMAniTex ani_tex;
	BMBlock block;
	BMLevel level;
int main( int argc, char **argv ){
    int videoFlags;
    SDL_Event event;
    const SDL_VideoInfo *videoInfo;
    if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ){
	    fprintf( stderr, "Video initialization failed: %s\n",
		     SDL_GetError( ) );
	    return 1;
	}
    videoInfo = SDL_GetVideoInfo( );
    if ( !videoInfo ){
	    fprintf( stderr, "Video query failed: %s\n",
		     SDL_GetError( ) );
	    return 1;
	}
    /* the flags to pass to SDL_SetVideoMode */
    videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
    videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
    videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
    //videoFlags |= SDL_RESIZABLE;       /* Enable window resizing */
    if ( videoInfo->hw_available )
	videoFlags |= SDL_HWSURFACE;
    else
	videoFlags |= SDL_SWSURFACE;
    if ( videoInfo->blit_hw )
	videoFlags |= SDL_HWACCEL;
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,videoFlags );
    if ( !screen ){
	    fprintf( stderr,  "Video mode set failed: %s\n", SDL_GetError( ) );
	    return 1;
	}

    /* Enable Texture Mapping ( NEW ) */
    glEnable( GL_TEXTURE_2D );

    /* Enable smooth shading */
    glShadeModel( GL_SMOOTH );

    /* Set the background black */
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );

    /* Depth buffer setup */
    glClearDepth( 1.0f );

    /* Enables Depth Testing */
    glEnable( GL_DEPTH_TEST );

    /* The Type Of Depth Test To Do */
    glDepthFunc( GL_LEQUAL );

    /* Really Nice Perspective Calculations */
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

    /* resize the initial window */GLfloat ratio;

    /* Protect against a divide by zero */

    ratio = ( GLfloat )SCREEN_WIDTH / ( GLfloat )SCREEN_HEIGHT;

    /* Setup our viewport. */
    glViewport( 0, 0, ( GLint )SCREEN_WIDTH, ( GLint )SCREEN_HEIGHT );

    /* change to the projection matrix and set our viewing volume. */
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );

    /* Set our perspective */
    gluPerspective( 45.0f, ratio, 0.1f, 100.0f );

    /* Make sure we're chaning the model view and not the projection */
    glMatrixMode( GL_MODELVIEW );

    /* Reset The View */
    glLoadIdentity( );



   //LOAD STUFF HERE
	//level.load("data/level/Smile.lvl");
	level.loadSmile();
	cur = BM_MENU;
	x = 0;
	y = 0;
	z = 0;
	x_rot = 0;
	y_rot = 0;
	z_rot = 0;
    /* wait for events */
    while ( bmGameLoop() ){
	    while ( SDL_PollEvent( &event ) ){
	        if( event.type == SDL_QUIT)
                return 0;
	    }
	}

    /* clean ourselves up and exit */
    SDL_Quit();

    /* Should never get here */
    return( 0 );
}

int bmGameLoop(){
	BMTimer timer;
    timer.setFPS(60);
	timer.start();
	keyboard.poll();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	switch(cur){
		case BM_MENU:
			//place menu function here (cur = menu.run(parameters maybe level, character))
			cur = BM_GAME;
			break;
		case BM_GAME:
			if(keyboard.hold(SDLK_UP))
				y -= 5.0f;
			if(keyboard.hold(SDLK_DOWN))
				y += 5.0f;
			if(keyboard.hold(SDLK_LEFT))
				x += 5.0f;
			if(keyboard.hold(SDLK_RIGHT))
				x -= 5.0f;
			if(keyboard.hold(SDLK_a))
				z += 5.0f;
			if(keyboard.hold(SDLK_s))
				z -= 5.0f;
			y_rot += 1.0f;
			level.rotate(x_rot,y_rot,z_rot);
			level.move(x,y,z);
			level.draw();
			break;
		default:
			break;
	}
    SDL_GL_SwapBuffers( );
	timer.frameDelay();
	return 1;
}
